package k.daniel.util.listener;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by daniel on 2015/7/15.
 */
public class DataSource<F> {
    Set<DataListener<F>> dataListeners = new HashSet<>();

    public int getListenerCount() {
        return dataListeners.size();
    }

    protected void beforeListenerAdded(DataListener<F> DataListener) {

    }

    /**
     * 当有监听器添加的时候触发
     * @param dataListener
     */
    protected void afterListenerAdded(DataListener<F> dataListener) {

    }

    protected void beforeListenerRemoved(DataListener<F> DataListener) {

    }

    /**
     * 当有监听器移除的时候触发
     * @param dataListener
     */
    protected void afterListenerRemoved(DataListener<F> dataListener) {
    }

    protected void beforeListenerRemoveAll() {

    }

    protected void afterListenerRemoveAll() {
    }

    /**
     * 注册监听器到数据源
     * @param DataListener
     * @return
     */
    public boolean registToDataSource(DataListener<F> DataListener) {
        boolean result = false;
        if (!dataListeners.contains(DataListener)) {
            beforeListenerAdded(DataListener);
            result = this.dataListeners.add(DataListener);
            afterListenerAdded(DataListener);
        }
        return result;
    }


    /**
     * 从数据源移除监听器
     * @param DataListener
     * @return
     */
    public synchronized boolean removeFromDataSource(DataListener<F> DataListener) {
        boolean result = false;
        synchronized (this)
        {
            if (dataListeners.contains(DataListener)) {
                beforeListenerRemoved(DataListener);
                result = this.dataListeners.remove(DataListener);
                afterListenerRemoved(DataListener);
            }
        }
        return result;
    }


    public synchronized void removeAll() {
        synchronized (this) {
            beforeListenerRemoveAll();
            dataListeners.clear();
            afterListenerRemoveAll();
        }
    }


    /**
     * 通知所有的监听器对事件作出反应
     * @param o
     */
    public void callAll(F o) {
        synchronized (this) {
            for (DataListener dataListener : dataListeners) {
                dataListener.onCalled(this, o);
            }
        }
    }

}
